#ifndef SYLAR_FIBER_H
#define SYLAR_FIBER_H

#include <ucontext.h>
#include <memory>
#include "thread.h"
#include <stdint.h>
#include <functional>
#include <atomic>
namespace sylar
{
    class Fiber : public std::enable_shared_from_this<Fiber>
    {
        
    public:
    friend class Scheduler;
        typedef std::shared_ptr<Fiber> ptr;
        enum State
        {
            INIT,
            HOLD,
            EXCEPT,
            EXEC,
            TERM,
            READY
        };
        // 状态	    英文含义	    中文解释	说明
        // INIT	    Initial	        初始状态	协程刚被创建，还未开始运行（构造函数执行完毕，但 m_cb 还没被调用）。
        // READY	Ready	        就绪状态	协程已经准备好运行，等待被调度器（scheduler）选中并切换到运行状态。
        // EXEC	    Executing	    运行状态	协程正在执行中（m_cb 函数正在运行）。
        // HOLD	    Holding     	暂停状态	协程主动暂停（比如调用 YieldToHold()），此时它让出 CPU 执行权，等待再次被唤醒。
        // EXCEPT	Exception	    异常状态	协程在执行过程中发生了未捕获的异常，导致状态变为异常。
        // TERM	    Terminated	    终止状态	协程的 m_cb 函数执行完毕，或者因异常退出，协程生命周期结束。
    private:
        Fiber();

    public:
        Fiber(std::function<void()> cb, size_t stacksize = 0,bool use_caller=false);
        ~Fiber();
        void reset(std::function<void()> new_cb);
        void call();
        void swapIn();
        void swapOut();
        void back();

        State getState() const;
        uint64_t getId() const
        {
            return m_id;
        }

    public:
        static void SetThis(Fiber *f);
        static Fiber::ptr GetThis();
        static void YieldToReady();
        static void YieldToHold();
        static uint64_t TotalFibers();
        static void MainFunction();
        static void CallerMainFunction();
        static uint64_t GetFiberId();
        State m_state = INIT;

    private:
        uint64_t m_id;
        uint32_t m_stacksize;

        ucontext_t m_ctx;
        void *m_stack = nullptr;
        std::function<void()> m_cb;
    };
}
#endif